<template>
  <div id="webgl-container" class="webgl-container">
    <canvas id="webgl" class="webgl"/>
  </div>

  <BuiltinGeometryInfo />
</template>

<script setup>
import {
  BoxGeometry,
  CircleGeometry,
  Color,
  ConeGeometry,
  CylinderGeometry,
  DodecahedronGeometry,
  DoubleSide,
  ExtrudeGeometry,
  Group,
  IcosahedronGeometry,
  LatheGeometry,
  Mesh,
  MeshBasicMaterial,
  OctahedronGeometry,
  PlaneGeometry,
  PolyhedronGeometry,
  RingGeometry,
  Shape,
  ShapeGeometry,
  SphereGeometry,
  TetrahedronGeometry,
  TorusGeometry,
  Vector2
} from 'three'

import { useThree } from '@/hooks/use-three-hook'

import BuiltinGeometryInfo from './BuiltInGeometryInfo.vue'

const { scene, camera, addAnimationCallback } = useThree()

onMounted(() => {
  if (scene.value && camera.value) {
    camera.value.position.z = 15

    // 材质
    const material = () => {
      return new MeshBasicMaterial({
        color: new Color(Math.random() * 0xffffff),
        side: DoubleSide,
        wireframe: true
      })
    }

    // 组合几何体
    const group = new Group()

    // 立方体
    const box = new BoxGeometry(1, 1, 1)
    const boxMesh = new Mesh(box, material())
    boxMesh.position.x = -10
    boxMesh.position.y = 5
    group.add(boxMesh)

    // 球体
    const sphere = new SphereGeometry(1, 32, 16)
    const sphereMesh = new Mesh(sphere, material())
    sphereMesh.position.x = -6
    sphereMesh.position.y = 5
    group.add(sphereMesh)

    // 平面
    const plane = new PlaneGeometry(2, 2)
    const planeMesh = new Mesh(plane, material())
    planeMesh.position.x = -2
    planeMesh.position.y = 5
    group.add(planeMesh)

    // 圆形
    const circle = new CircleGeometry(1, 32)
    const circleMesh = new Mesh(circle, material())
    circleMesh.position.x = 2
    circleMesh.position.y = 5
    group.add(circleMesh)

    // 圆柱体
    const cylinder = new CylinderGeometry(1, 1, 2, 32)
    const cylinderMesh = new Mesh(cylinder, material())
    cylinderMesh.position.x = 6
    cylinderMesh.position.y = 5
    group.add(cylinderMesh)

    // 圆锥体
    const cone = new ConeGeometry(1, 2, 32)
    const coneMesh = new Mesh(cone, material())
    coneMesh.position.x = 10
    coneMesh.position.y = 5
    group.add(coneMesh)

    // 环形/甜甜圈形状
    const torus = new TorusGeometry(1, 0.5, 32, 100)
    const torusMesh = new Mesh(torus, material())
    torusMesh.position.x = -10
    torusMesh.position.y = 0
    group.add(torusMesh)

    // 四面体
    const tetrahedron = new TetrahedronGeometry(2, 0)
    const tetrahedronMesh = new Mesh(tetrahedron, material())
    tetrahedronMesh.position.x = -6
    tetrahedronMesh.position.y = 0
    group.add(tetrahedronMesh)

    // 八面体
    const octahedron = new OctahedronGeometry(2, 0)
    const octahedronMesh = new Mesh(octahedron, material())
    octahedronMesh.position.x = -2
    octahedronMesh.position.y = 0
    group.add(octahedronMesh)

    // 十二面体
    const dodecahedron = new DodecahedronGeometry(1.5, 0)
    const dodecahedronMesh = new Mesh(dodecahedron, material())
    dodecahedronMesh.position.x = 2
    dodecahedronMesh.position.y = 0
    group.add(dodecahedronMesh)

    // 二十面体
    const icosahedron = new IcosahedronGeometry(1.5, 0)
    const icosahedronMesh = new Mesh(icosahedron, material())
    icosahedronMesh.position.x = 6
    icosahedronMesh.position.y = 0
    group.add(icosahedronMesh)

    // 自定义多面体
    const verticesOfCube = [
      -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1,
      -1, 1, 1
    ]

    const indicesOfFaces = [
      2, 1, 0, 0, 3, 2, 0, 4, 7, 7, 3, 0, 0, 1, 5, 5, 4, 0, 1, 2, 6, 6, 5, 1, 2,
      3, 7, 7, 6, 2, 4, 5, 6, 6, 7, 4
    ]

    const polyhedron = new PolyhedronGeometry(
      verticesOfCube,
      indicesOfFaces,
      1.5,
      2
    )
    const polyhedronMesh = new Mesh(polyhedron, material())
    polyhedronMesh.position.x = 10
    polyhedronMesh.position.y = 0
    group.add(polyhedronMesh)

    // 环形平面
    const ring = new RingGeometry(1, 1.5, 16)
    const ringMesh = new Mesh(ring, material())
    ringMesh.position.x = -10
    ringMesh.position.y = -5
    group.add(ringMesh)

    // 管道几何体

    // 拉伸几何体
    const length = 1,
      width = 1

    const shape = new Shape()
    shape.moveTo(0, 0)
    shape.lineTo(0, width)
    shape.lineTo(length, width)
    shape.lineTo(length, 0)
    shape.lineTo(0, 0)

    const extrudeSettings = {
      steps: 1,
      depth: 1,
      bevelEnabled: true,
      bevelThickness: 1,
      bevelSize: 1,
      bevelOffset: 0,
      bevelSegments: 1
    }

    const extrude = new ExtrudeGeometry(shape, extrudeSettings)
    const extrudeMesh = new Mesh(extrude, material())
    extrudeMesh.position.x = -2
    extrudeMesh.position.y = -5
    group.add(extrudeMesh)

    // 旋转几何体
    const points = []
    for (let i = 0; i < 10; i++) {
      points.push(new Vector2(Math.sin(i * 0.2) + 0.3, (i - 5) * 0.3))
    }
    const lathe = new LatheGeometry(points, 16)
    const latheMesh = new Mesh(lathe, material())
    latheMesh.position.x = 2
    latheMesh.position.y = -5
    group.add(latheMesh)

    // 形状几何体
    const x = 0,
      y = 0
    const heartShape = new Shape()

    heartShape.moveTo(x + 5, y + 5)
    heartShape.bezierCurveTo(x + 5, y + 5, x + 4, y, x, y)
    heartShape.bezierCurveTo(x - 6, y, x - 6, y + 7, x - 6, y + 7)
    heartShape.bezierCurveTo(x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19)
    heartShape.bezierCurveTo(x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7)
    heartShape.bezierCurveTo(x + 16, y + 7, x + 16, y, x + 10, y)
    heartShape.bezierCurveTo(x + 7, y, x + 5, y + 5, x + 5, y + 5)

    const shapeGeo = new ShapeGeometry(heartShape)
    const shapeMesh = new Mesh(shapeGeo, material())
    shapeMesh.position.x = 6
    shapeMesh.position.y = -5
    shapeMesh.scale.set(0.1, 0.1, 0.1)
    group.add(shapeMesh)

    // 文本几何体

    scene.value.add(group)

    addAnimationCallback(delta => {
      group.children.forEach(mesh => {
        // mesh.rotation.x += delta
        mesh.rotation.y += delta * 0.5
        // mesh.rotation.z += delta * 0.5
      })
    })
  }
})
</script>
